Commit | Line | Data |
---|---|---|
ee49ff3d CE |
1 | // arcade controller thing |
2 | // Copyright (c) 2017 Clinton Ebadi <clinton@unknownlamer.org> | |
3 | // GPLv3 or (at your option) any later version | |
4 | // .. insert license text here ... | |
5 | ||
9571d749 CE |
6 | // todo: |
7 | // - hinge | |
8 | // - screw holes + captive nut to mount | |
9 | // - internal mount for mcu and battery | |
10 | // - hole for usb panel mount | |
11 | // - bevel lid | |
12 | ||
13 | // maybe/wishlist: | |
14 | // - wire routing clips on panel? | |
15 | // - buttons on side for pinball? | |
16 | // - vent under mcu/battery? | |
17 | // - slant panel toward player? | |
18 | ||
19 | // bugs: | |
20 | // - hinge is not aligned -- either male arm length or connector placement is wrong | |
21 | ||
ee49ff3d | 22 | use <obiscad/bcube.scad> |
c3a57278 | 23 | use <obiscad/attach.scad> |
7db674d2 CE |
24 | use <joints.scad> |
25 | ||
c3a57278 | 26 | // PREVIEW |
7db674d2 | 27 | preview(); |
9571d749 | 28 | |
7db674d2 | 29 | module preview () { |
f6620219 | 30 | rotate ([-10, 0, 0]) translate ([0, 0, box_depth+20]) panel (); |
c3a57278 | 31 | case (); |
f6620219 | 32 | for (i = [2 ,4]) translate ([panel_width+hinge_joint_width*i, 0, 0]) hinge_male (); |
c3a57278 | 33 | |
9571d749 | 34 | } |
c3a57278 CE |
35 | |
36 | // CONFIGURATION | |
37 | ||
f6620219 CE |
38 | panel_width = 250; |
39 | panel_height = 130; | |
c3a57278 | 40 | |
f6620219 | 41 | box_depth = 80; |
c3a57278 | 42 | box_wall = 2; |
f6620219 | 43 | box_base_thickness = 5; |
c3a57278 | 44 | |
9571d749 | 45 | $button_d = 30; // I think this should be special |
ee49ff3d | 46 | |
f6620219 CE |
47 | joystick_width = 85; |
48 | joystick_height = 40; | |
c3a57278 | 49 | |
9571d749 | 50 | // fixme: these are a bit confused |
f6620219 | 51 | hinge_joint_width = 8; |
7db674d2 | 52 | hinge_joint_thickness = 5; |
f6620219 | 53 | hinge_box_base_thicknesseight = 10; |
9571d749 CE |
54 | hinge_joint_height = 10; |
55 | hinge_arm_length = 50; | |
56 | ||
57 | ||
58 | // gunk that should be elsewhere... | |
59 | // bcube parameters, clean up | |
60 | cr = box_wall*2; | |
61 | cres = 0; | |
7db674d2 | 62 | |
c3a57278 | 63 | // PANEL COMPONENTS |
ee49ff3d CE |
64 | |
65 | module button (bezel = $button_d+4) { | |
66 | circle (d=$button_d); | |
67 | %circle(d=bezel); | |
68 | } | |
69 | ||
ee49ff3d CE |
70 | module joystick () { |
71 | bolt_d = 8; | |
72 | center_hole_d = 24; | |
73 | ||
f6620219 | 74 | for (x = [-joystick_width/2, joystick_width/2], y = [-joystick_height/2, joystick_height/2]) { |
ee49ff3d CE |
75 | translate ([x, y, 0]) circle (d=bolt_d); // need slot instead |
76 | } | |
c3a57278 | 77 | circle (d=center_hole_d); |
f6620219 | 78 | %square ([joystick_width, joystick_height], center=true); // not right... |
ee49ff3d CE |
79 | } |
80 | ||
ee49ff3d | 81 | |
c3a57278 | 82 | // CASE |
ee49ff3d | 83 | |
f6620219 CE |
84 | module case_base (h=box_base_thickness) { |
85 | bcube([panel_width, panel_height, h], cr, cres); | |
ee49ff3d CE |
86 | } |
87 | ||
c3a57278 | 88 | module case_walls () { |
9571d749 CE |
89 | difference () { |
90 | union () { | |
91 | difference() { | |
f6620219 CE |
92 | bcube([panel_width, panel_height, box_depth-box_base_thickness], cr, cres); |
93 | bcube([panel_width-box_wall*2, panel_height-box_wall*2, box_depth+1], cr, cres); | |
9571d749 CE |
94 | } |
95 | attach (case_connector_wall (x=10), hinge_connector_back ()) hinge_female_base (); | |
96 | } | |
97 | attach (case_connector_wall (x=10), hinge_connector_back ()) hinge_female_cut (); | |
ee49ff3d | 98 | } |
7db674d2 | 99 | %connector (case_connector_wall (x=10)); |
ee49ff3d CE |
100 | } |
101 | ||
c3a57278 CE |
102 | module case () { |
103 | case_base (); | |
f6620219 | 104 | translate ([0, 0, box_depth/2]) case_walls (); |
7db674d2 CE |
105 | } |
106 | ||
107 | ||
108 | // todo: | |
9571d749 CE |
109 | // specify which wall (rear, front, left, right). vector addition may help... |
110 | // offset from center of wall, as vector (and use vector subtraction!) | |
7db674d2 | 111 | // optional: inside/outside |
f6620219 | 112 | function case_connector_wall (x=0, y=0, z=0) = [ [panel_width/2-x, panel_height/2-y, (box_depth-box_base_thickness)/2-z], [0,-1, 0], 0 ]; |
7db674d2 CE |
113 | |
114 | // HINGE | |
115 | ||
9571d749 CE |
116 | // hinge todo: |
117 | // calculate z offset so that hinge will align when closed | |
118 | // calculate offset into panel surface for length of peg | |
119 | // attach to case, calculating offset from wall as fixed value + width | |
120 | ||
121 | // add connector for pin to socket so that can easily be test fit in | |
122 | // software instead of guessing | |
123 | ||
124 | // should panel connector be on its side? Limits motion to 90⁰ Or | |
125 | // maybe just walls only + fillet with no base... | |
126 | ||
f6620219 | 127 | function hinge_connector_back (th=hinge_joint_thickness*2, h=hinge_box_base_thicknesseight) = [ [0, th/2, h/2], [0,1, 0], 0 ]; |
7db674d2 | 128 | |
9571d749 CE |
129 | // todo: |
130 | // gusset support underneath | |
131 | // split into base and negative so that a hole can be punched into case wall | |
132 | ||
133 | module hinge_female_base () { | |
134 | w = hinge_joint_width * 2; | |
135 | th = hinge_joint_thickness * 2; | |
136 | ||
137 | %connector (hinge_connector_back ()); | |
f6620219 | 138 | cube ([w, th, hinge_box_base_thicknesseight], center=true); |
9571d749 CE |
139 | } |
140 | ||
141 | module hinge_female_cut () { | |
7db674d2 CE |
142 | w = hinge_joint_width * 2; |
143 | th = hinge_joint_thickness * 2; | |
9571d749 CE |
144 | |
145 | // cruft from earlier hacking, remove... | |
7db674d2 CE |
146 | jt = hinge_joint_thickness; |
147 | jw = hinge_joint_width; | |
7db674d2 | 148 | |
9571d749 CE |
149 | joint_male_negative(male_joint_width=jw, male_joint_thickness=jt, forward_rom=90, backward_rom=90, male_joint_height=hinge_joint_height); |
150 | } | |
7db674d2 | 151 | |
9571d749 | 152 | module hinge_female () { |
7db674d2 | 153 | difference () { |
9571d749 CE |
154 | hinge_female_base (); |
155 | hinge_female_cut (); | |
7db674d2 | 156 | } |
ee49ff3d CE |
157 | } |
158 | ||
9571d749 CE |
159 | module hinge_male () { |
160 | for (i=[0,1]) mirror ([0, i, 0]) translate ([0, -hinge_arm_length/4, 0]) | |
161 | joint_male(male_joint_width=hinge_joint_width, male_joint_thickness=hinge_joint_thickness, male_joint_height=hinge_arm_length/2, side=true); | |
162 | ||
163 | } | |
164 | ||
165 | ||
166 | // hinge to panel... | |
167 | // mount hinge on panel arm_length back from edge | |
168 | ||
169 | // fixme: wall thickness is not taken into account | |
ee49ff3d | 170 | |
c3a57278 | 171 | // PANEL |
ee49ff3d | 172 | |
9571d749 CE |
173 | |
174 | // cleanup after general case_connector_wall() is done | |
f6620219 | 175 | panel_c = [ [panel_width/2-10, panel_height/2-hinge_arm_length, -box_base_thickness/2+0.01], [0,0, 1], 180 ]; |
9571d749 | 176 | |
ee49ff3d CE |
177 | module panel () { |
178 | difference () { | |
c3a57278 | 179 | case_base (); |
f6620219 | 180 | linear_extrude (box_base_thickness*2,center=true) panel_layout (); |
ee49ff3d | 181 | } |
9571d749 CE |
182 | %connector (panel_c); |
183 | attach (panel_c, hinge_connector_back ()) hinge_female (); | |
ee49ff3d CE |
184 | } |
185 | ||
c3a57278 CE |
186 | module panel_attach (position, angle=0) { |
187 | x = position[0]; | |
188 | y = position[1]; | |
f6620219 | 189 | c1 = [ [x, y, box_base_thickness/2], [0,0,1], angle ]; |
c3a57278 | 190 | a1 = [ [0,0, 0], [0,0,0], 0 ]; |
7db674d2 | 191 | // %connector (c1); // fixme: don't use 2d for layout |
c3a57278 CE |
192 | attach (c1, a1) children (); |
193 | } | |
ee49ff3d | 194 | |
c3a57278 | 195 | // panel layout inspired by the Neo Geo layout |
ee49ff3d | 196 | module panel_layout () { |
f6620219 | 197 | translate ([-panel_width/2 + 40, 0, 0]) { |
c3a57278 CE |
198 | panel_attach ([0, 0], 90) joystick (); |
199 | ||
200 | // p1, coin (floating off in the distance...) | |
9571d749 | 201 | translate ([140, 0, 0]) { |
7db674d2 | 202 | $button_d=16; |
c3a57278 | 203 | for (x = [0, $button_d+10]) { |
7db674d2 | 204 | panel_attach ([x, 42]) button (); |
c3a57278 CE |
205 | } |
206 | } | |
ee49ff3d | 207 | |
c3a57278 | 208 | // a, b, c, d |
7db674d2 CE |
209 | translate ([60, -20, 0]) { |
210 | panel_attach ([0, 0]) button (); | |
c3a57278 | 211 | for (i = [ 1 : 3 ]) { |
7db674d2 | 212 | panel_attach ([i*($button_d+10)-10, $button_d]) button (); |
c3a57278 | 213 | } |
ee49ff3d CE |
214 | } |
215 | } | |
216 | } |